package com.secret.chain.secretchain.utils;

import com.secret.chain.secretchain.BO.*;
import com.secret.chain.secretchain.solidity.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;


/**
 * 交易Service
 */
@Service
@Slf4j
public class ContractServiceImpl {


    @Autowired
    public Client client;


    /**
     * 保存用户地址信息
     */
    public CryptoKeyPair cryptoSuiteOfUser;//用户

    public ContractServiceImpl(){

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
        BcosSDK bcosSDK = context.getBean(BcosSDK.class);
        Client client1 = bcosSDK.getClient(1);
        cryptoSuiteOfUser = client1.getCryptoSuite().getCryptoKeyPair();
    }


    /**
     * 创建用户
     * @param userBO
     * @return
     * @throws ContractException
     */
    //address 合约地址 0 已创建 1 未创建
    public AddressBO setUser(String address, UserBO userBO) throws ContractException {
        //部署合约
        User user;
        if (StringUtils.isEmpty(address)){
            user = User.deploy(client, cryptoSuiteOfUser);
        }else {
            user = User.load(address,client,cryptoSuiteOfUser);
        }

        AddressBO addressBO = new AddressBO();
        //添加地址
        addressBO.setAddress(user.getContractAddress());
        TransactionReceipt transactionReceipt = user.setUser(
                userBO.getName(),
                userBO.getAvatar(),
                userBO.getIntro(),
                userBO.getPhone()
        );
        //交易哈希
        addressBO.setHash(transactionReceipt.getTransactionHash());

        TransactionReceipt transactionReceipt1 = user.setInfo(
                userBO.getBalance(),
                userBO.getCreate(),
                userBO.getUpdate(),
                userBO.getStatus(),
                userBO.getFollow(),
                userBO.getFans(),
                userBO.getOpenId()
        );
        return  addressBO;
    }

    /**
     * 查询用户
     * @param address 合约地址
     * @return
     * @throws ContractException
     */
    public UserBO getUser(String address)throws ContractException{
        User user = User.load(address, client, cryptoSuiteOfUser);
        UserBO userBO = new UserBO(user.name(),user.avatar(),user.intro(),user.phone(),user.balance(),user.create(),user.update(),user.status(),user.follow(),user.fans(),user.openID());


        return userBO;

    }

    /**
     * 设置问题
     * @param address
     * @param problemBO
     * @return
     * @throws ContractException
     */
    public  AddressBO setProblem(String address , ProblemBO problemBO) throws ContractException {
        Problem problem;
        if (StringUtils.isEmpty(address)){
            problem =  Problem.deploy(client,cryptoSuiteOfUser);
        }else {
            problem = Problem.load(address,client,cryptoSuiteOfUser);
        }
        AddressBO addressBO = new AddressBO();
        addressBO.setAddress(problem.getContractAddress());
        TransactionReceipt transactionReceipt = problem.set(problemBO.getAskId(), problem.answerId(), problem.groupId(), problem.content(), problem.status(), problem.create(), problem.update());
        addressBO.setHash(transactionReceipt.getTransactionHash());
        return addressBO;
    }

    public  AddressBO setProblem(ProblemBO problemBO) throws ContractException {
        Problem problem;
        String address="";
        if (StringUtils.isEmpty(address)){
            problem =  Problem.deploy(client,cryptoSuiteOfUser);
        }else {
            problem = Problem.load(address,client,cryptoSuiteOfUser);
        }
        AddressBO addressBO = new AddressBO();
        addressBO.setAddress(problem.getContractAddress());
        TransactionReceipt transactionReceipt = problem.set(problemBO.getAskId(), problem.answerId(), problem.groupId(), problem.content(), problem.status(), problem.create(), problem.update());
        addressBO.setHash(transactionReceipt.getTransactionHash());
        return addressBO;
    }

    /**
     * 查询问题
     * @param address
     * @return
     * @throws ContractException
     */
    public ProblemBO getProblem(String address)throws ContractException {
        Problem problem = Problem.load(address, client, cryptoSuiteOfUser);
        ProblemBO problemBO = new ProblemBO(problem.askId(), problem.answerId(), problem.groupId(), problem.content(), problem.status(), problem.create(), problem.update());
        return  problemBO;
    }

    /**
     * 添加collect
     * @param address
     * @param collectBO
     * @return
     * @throws ContractException
     */
    public  AddressBO setCollect(String address , CollectBO collectBO)throws ContractException{
        Collect collect;
        if (StringUtils.isEmpty(address)){
            collect =  Collect.deploy(client,cryptoSuiteOfUser);
        }else {
            collect = Collect.load(address,client,cryptoSuiteOfUser);
        }
        AddressBO addressBO = new AddressBO();
        addressBO.setAddress(collect.getContractAddress());
        TransactionReceipt transactionReceipt = collect.set(collectBO.getUserId(), collectBO.getArticleId(), collectBO.getCreate(), collectBO.getUpdate(), collectBO.getStatus());
        addressBO.setHash(transactionReceipt.getTransactionHash());
        return addressBO;
    }

    /**
     * 查询collect
     * @param address
     * @return
     * @throws ContractException
     */
    public  CollectBO getCollect(String address)throws ContractException{
        Collect collect = Collect.load(address, client, cryptoSuiteOfUser);
        CollectBO collectBO = new CollectBO(collect.userId(), collect.articleId(), collect.create(), collect.update(), collect.status());
        return  collectBO;
    }

    /**
     * 写入Article
     * @param address
     * @param articleBO
     * @return
     * @throws ContractException
     */
    public AddressBO setArticle(String address , ArticleBO articleBO)throws ContractException{
        Article article;
        if (StringUtils.isEmpty(address)){
            article =  Article.deploy(client,cryptoSuiteOfUser);
        }else {
            article = Article.load(address,client,cryptoSuiteOfUser);
        }
        AddressBO addressBO = new AddressBO();
        addressBO.setAddress(article.getContractAddress());
        TransactionReceipt transactionReceipt = article.set1(articleBO.getCreatorId(), articleBO.getGroupId(), articleBO.getTitle(), articleBO.getContent(), articleBO.getCreate());
        TransactionReceipt transactionReceipt1 = article.set2(articleBO.getLikeCount(), articleBO.getCollectCount(), articleBO.getForwardCount(), articleBO.getReadCount(), articleBO.getUpdate(), articleBO.getStatus());
        addressBO.setHash(transactionReceipt.getTransactionHash());
        return  addressBO;
    }

    /**
     * 查询Article
     * @param address
     * @return
     * @throws ContractException
     */
    public ArticleBO getArticle(String address)throws ContractException{
        Article article = Article.load(address, client, cryptoSuiteOfUser);
        ArticleBO articleBO = new ArticleBO(article.creatorId(), article.groupId(), article.title(), article.content(), article.likeCount(), article.collectCount(), article.forwardCount(), article.readCount(), article.create(), article.update(), article.status());
        return  articleBO;
    }

    /**
     * 写入Answer
     * @param address
     * @param answerBO
     * @return
     * @throws ContractException
     */
    public AddressBO setAnswer(String address , AnswerBO answerBO)throws ContractException{
        Answer answer;
        if (StringUtils.isEmpty(address)){
            answer =  Answer.deploy(client,cryptoSuiteOfUser);
        }else {
            answer = Answer.load(address,client,cryptoSuiteOfUser);
        }
        AddressBO addressBO = new AddressBO();
        addressBO.setAddress(answer.getContractAddress());
        TransactionReceipt transactionReceipt = answer.set(answerBO.getProblemId(), answerBO.getContent(), answerBO.getCreate(), answerBO.getUpdate(), answerBO.getStatus());
        addressBO.setHash(transactionReceipt.getTransactionHash());
        return  addressBO;
    }

     /**
      * 查询Answer
      * @param address
      * @return
      * throws ContractException
       * */
    public  AnswerBO getAnswer(String address)throws ContractException{
        Answer answer = Answer.load(address, client, cryptoSuiteOfUser);
        AnswerBO answerBO = new AnswerBO(answer.problemId(), answer.content(), answer.create(), answer.update(), answer.status());
        return  answerBO;
    }

}
